<template>
  <div class="flow-content">
    <!-- <button @click="clearAllEvents">移除所有事件</button> -->
    <!-- 流程引擎 -->
    <flowEditor
      v-if="flowData.modelId"
      ref="flowEditor"
      :config="config"
      @btn-save-click="handleSaveBtn"
      :contextmenuList="contextmenuList"
      @editorInitCompleted="editorInitCompleted"
      @oncontextmenu="handleContextmenu"
      @doubleClick="doubleClick"
      @doubleClickToChangeVal="doubleClickToChangeVal"
      @clickContextmenuCommand="handleContextmenuCommand"
      @selection-changed="selectionChanged"
    >
      <template slot="paletteWrapper" slot-scope="scope">
        <div id="paletteHelpWrapper" class="paletteHelpWrapper" v-if="scope.editorManager">
          <div class="stencils" id="paletteSection">
            <template v-for="group in scope.editorManager.showStencilData">
              <div :key="group.id" v-if="group.visible && group.items" class="stencil-group">
                <p class="group-name">{{ group.name }}</p>
                <ul :key="group.id" v-if="group.visible && group.items">
                  <li v-for="item in group.paletteItems" :key="item.id">
                    <stencil-drag-item :item="item" :editorManager="scope.editorManager"></stencil-drag-item>
                  </li>
                </ul>
              </div>
            </template>
          </div>
        </div>
      </template>
      <!-- 底部属性显示区域table -->
      <template slot="propertyWrapper" slot-scope="scope">
        <span>{{ stateEditorManager(scope.editorManager) }}</span>
        <!-- <propertySection
          v-if="scope.editorManager && scope.editorManager.modelData.model"
          :modelData="scope.editorManager.modelData.model"
        ></propertySection> -->
      </template>
    </flowEditor>

    <!-- 保存模型弹窗 -->
    <el-dialog title="保存流程" class="save-dialog" :visible="saveVisible" append-to-body @close="close" width="60%">
      <div
        v-if="saveDialog.errorMessage && saveDialog.errorMessage.length > 0"
        class="alert error"
        style="font-size: 14px; margin-top:20px"
      >
        <div class="popup-error" style="font-size: 14px">
          <span class="glyphicon glyphicon-remove-circle"></span>
          <span>{{ saveDialog.errorMessage }}</span>
        </div>
      </div>
      <el-form label-width="46px" :model="nodeObjProperties" class="demo-form-inline">
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="名称">
              <el-input
                :disabled="saveLoading || (error && error.conflictResolveAction == 'saveAs')"
                v-model="saveDialog.name"
                placeholder="请输入"
              ></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="Key">
              <!-- <el-input
                :disabled="saveLoading || (error && error.conflictResolveAction == 'saveAs')"
                v-model="saveDialog.key"
                placeholder="请输入"
              ></el-input> -->
              <el-input :disabled="true" v-model="saveDialog.key" placeholder="请输入"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="描述">
          <el-input
            :disabled="saveLoading"
            class="form-control"
            v-model="saveDialog.description"
            placeholder="请输入"
          ></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <div>
          <el-button @click="close" :disabled="saveLoading">取消</el-button>
          <el-button
            type="primary"
            @click="save"
            :disabled="
              (saveDialog.name && saveDialog.name.length === 0) || (saveDialog.key && saveDialog.key.length === 0)
            "
          >
            保存
          </el-button>
        </div>
      </span>
    </el-dialog>

    <!-- 编辑节点信息 -->
    <el-dialog
      class="edit-dialog"
      :title="writeDialog.title"
      :visible.sync="writeDialog.visible"
      :close-on-click-modal="false"
      width="70%"
      :before-close="handlepropertyWriteClose"
    >
      <div>
        <div class="node-content">
          <el-form label-width="86px" :model="nodeObjProperties" class="demo-form-inline">
            <el-row :gutter="30">
              <el-col :span="12">
                <el-form-item label="编号">
                  <el-input v-model="nodeObjProperties.overrideid" disabled placeholder="请输入"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="名称">
                  <el-input v-model="nodeObjProperties.name" placeholder="请输入"></el-input>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row :gutter="30">
              <el-col :span="12" v-if="isNode">
                <el-form-item label="分配角色">
                  <el-select v-model="nodeObjProperties.taskroleids" placeholder="请选择">
                    <el-option
                      v-for="item in assignRole"
                      :key="item.roleId"
                      :label="item.roleName"
                      :value="item.roleId"
                    >
                    </el-option>
                  </el-select>
                </el-form-item>
              </el-col>
              <!-- <el-col :span="12">
                <el-form-item label="阶段策略">
                  <el-button @click="stageStrategyFun(nodeObjProperties)">点击设置</el-button>
                </el-form-item>
              </el-col> -->
              <el-col :span="12" v-if="isNode">
                <el-form-item label="多实例类型">
                  <el-select v-model="nodeObjProperties.multiinstance_type" placeholder="请选择">
                    <el-option
                      v-for="item in multiinstanceTypeList"
                      :key="item.value"
                      :label="item.label"
                      :value="item.value"
                    >
                    </el-option>
                  </el-select>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row :gutter="30">
              <el-col :span="12">
                <el-form-item label="说明">
                  <el-input type="textarea" autosize v-model="nodeObjProperties.des" placeholder="请输入"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="12" v-if="!isNode">
                <el-form-item label="流转策略">
                  <el-button @click="sequenseflowStrategyFun(nodeObjProperties)">点击设置</el-button>
                </el-form-item>
              </el-col>
              <el-col :span="12" v-if="isNode">
                <el-form-item label="阶段策略">
                  <el-button @click="stageStrategyFun(nodeObjProperties)">点击设置</el-button>
                </el-form-item>
              </el-col>
            </el-row>
          </el-form>
        </div>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="writeDialog.visible = false">取 消</el-button>
        <el-button type="primary" @click="handlebubbleEvents('goToRefTask')">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import Vue from 'vue'
import flowEditor from 'flow-editor-vue'
import { AA } from './stencilData-kpm.js'
import { defaultData } from './default.js'
// import { mockData } from './mockData.js'
import configure from './initConfig'
import './styles/src/index.scss'
Vue.use(flowEditor)

const TaskNoneQuote = [
  {
    name: '属性',
    action: 'createQuote',
    type: 'dialog',
    dialogTitle: '属性'
    // componentTemplate: 'refActivity'
  }
]
const TaskQuoted = [
  {
    name: '查看/编辑',
    action: 'modifyActivity',
    type: 'dialog',
    dialogTitle: '活动主数据维护'
    // componentTemplate: 'activityTabsEdit'
  }
]

export default {
  name: 'FlowEditorVue',
  data() {
    return {
      showFlow: false,
      config: {
        type: 'flow',
        modelData: this.flowData,
        stencilData: AA,
        pluginConfig: {
          properties: [
            { group: 'File', index: 1 },
            { group: 'Edit', index: 2 },
            { group: 'Undo', index: 3 },
            { group: 'Alignment', index: 4 },
            { group: 'Group', index: 5 },
            { group: 'Z-Order', index: 6 },
            { group: 'Docker', index: 7 },
            { group: 'Zoom', index: 8 }
          ],
          plugins: [
            { name: 'Plugins.Loading' },
            { name: 'Plugins.CanvasResize', notUsesIn: 'xforms' },
            { name: 'Plugins.ProcessLink' },
            { name: 'Plugins.Arrangement' },
            { name: 'Plugins.Save' },
            { name: 'Plugins.View' },
            { name: 'Plugins.DragDropResize' },
            { name: 'Plugins.NodesResize' },
            { name: 'Plugins.PoolResize' },
            { name: 'Plugins.HighlightingSelectedShapes' },
            { name: 'Plugins.DragDocker' },
            { name: 'Plugins.AddDocker' },
            { name: 'Plugins.DragVisual' },
            { name: 'Plugins.SelectionFrame' },
            { name: 'Plugins.ShapeHighlighting' },
            { name: 'Plugins.Overlay' },
            { name: 'Plugins.KeysMove' },
            { name: 'Plugins.Layouter.EdgeLayouter' },
            { name: 'Plugins.BPMN2_0' },
            { name: 'Plugins.RenameShapes' },
            { name: 'Plugins.PoolAsProperty' }
            // { name: 'EndFlowPlugin', plugin: EndFlowPlugin, type: 'custom' }
          ]
        },
        editorConfigs: configure
      },
      editorManager: null,
      form: {},
      contextmenuList: [],
      selectedItem: {},
      currentShapeMode: 'read',
      writeDialog: {
        visible: false,
        componentTemplate: null
      },
      saveVisible: false,
      saveDialog: {
        name: this.flowData.name,
        key: this.flowData.key,
        errorMessage: [],
        description: this.flowData.description,
        comment: '',
        // user: this.flowData.lastUpdatedBy,
        lastUpdated: this.flowData.lastUpdated,
        lastUpdatedBy: this.flowData.lastUpdatedBy,
        modelId: this.flowData.modelId,
        version: this.flowData.version,
        newversion: false
      },
      saveLoading: false,
      error: null,
      // 属性
      nodeObjProperties: {},
      isNode: true,
      multiinstanceTypeList: [
        {
          id: 1,
          label: '无',
          value: 'None'
        },
        {
          id: 2,
          label: '并行',
          value: 'Parallel'
        },
        {
          id: 3,
          label: '串行',
          value: 'Sequential'
        }
      ]
    }
  },
  // components: { propertySection, refActivity, activityTabsEdit },
  computed: {
    modelData() {
      return this.editorManager ? this.editorManager.getModel() : { properties: {} }
    }
  },
  props: {
    assignRole: {
      type: Array,
      default: () => []
    },
    flowData: {
      type: Object,
      default: () => defaultData
    }
  },
  mounted() {
    this.showFlow = true
  },
  methods: {
    /**
     * 初始化
     */
    editorInitCompleted() {},
    /**
     * 点击节点/连接线
     */
    selectionChanged(event) {
      const typeId = event.selectedShape && event.selectedShape._svgShapes
      if (typeId) {
        this.isNode = true
      } else {
        this.isNode = false
      }
      if (this.currentShapeMode !== 'write') {
        this.selectedItem = event.selectedItem
        this.selectedShape = event.selectedShape
      }
    },

    /**
     * 点击保存事件
     */
    handleSaveBtn() {
      // handleSaveBtn (editor) {
      this.save()
      // this.saveVisible = true
      // this.editorManager = editor
    },
    /**
     * 保存
     */
    save() {
      let json = this.editorManager.getModel()
      json.properties = {
        ...json.properties,
        ...this.saveDialog
      }
      this.editorManager.handleEvents({
        type: 'editorSaved'
      })

      let params = {
        modeltype: this.flowData.model.modelType,
        json_xml: JSON.stringify(json),
        name: this.saveDialog.name,
        key: this.saveDialog.key,
        description: this.saveDialog.description,
        newversion: this.saveDialog.newversion,
        comment: this.saveDialog.comment,
        lastUpdated: this.saveDialog.lastUpdated
      }
      this.$emit('saveFlow', params)
      // this.saveVisible = false
      // let params = {
      //   modelId: '6609363a-3be5-11e9-afe0-82ad27eff10d',
      //   name: '请假模型',
      //   key: 'leave-model',
      //   description: '请假模型',
      //   lastUpdated: '2019-04-04T05:49:37.132+0000',
      //   lastUpdatedBy: 'admin',
      //   model: json,
      //   ...this.saveDialog
      // }
    },
    /**
     * 保存模型信息后关闭弹窗
     */
    saveSuccess() {
      this.saveVisible = false
    },
    /**
     * 移除所有事件
     */
    clearAllEvents() {
      this.editorManager.clearAllEvents()
    },
    /**
     * 关闭模型信息弹窗
     */
    close() {
      this.saveVisible = false
    },
    /**
     * 刷新全局信息
     */
    stateEditorManager(editor) {
      this.editorManager = editor
    },
    /**
     * 鼠标右键
     */
    handleContextmenu({ selectedElements }) {
      if (selectedElements.length === 1) {
        let currentShape = selectedElements[0]
        if (currentShape.getStencil().idWithoutNs() === 'UserTask') {
          let value = currentShape.properties.get('refId')
          this.contextmenuList = value ? TaskQuoted : TaskNoneQuote
        }
        this.$refs.flowEditor.showContextmenu()
      }
    },
    /**
     * 鼠标右键点击菜单列表
     */
    handleContextmenuCommand(params) {
      if (params.action.type === 'dialog') {
        this.writeDialog = {
          visible: true,
          title: params.action.dialogTitle,
          componentTemplate: params.action.componentTemplate
        }

        this.nodeObjProperties = {
          ...this.selectedShape.hiddenProperties._object,
          ...this.selectedShape.properties._object
        }
      }
    },
    /**
     * 属性弹窗关闭之前
     */
    handlepropertyWriteClose() {
      this.currentShapeMode = 'read'
      this.writeDialog.visible = false
    },

    /**
     * 更新节点属性及名称
     */
    updatePropertyInModel({ properties, shapeId }) {
      let shape = this.selectedShape
      // Some updates may happen when selected shape is already changed, so when an additional
      // shapeId is supplied, we need to make sure the correct shape is updated (current or previous)
      if (shapeId) {
        if (shape.id !== shapeId && this.previousSelectedShape && this.previousSelectedShape.id === shapeId) {
          shape = this.previousSelectedShape
        } else {
          shape = null
        }
      }

      if (!shape) {
        return
      }

      const _this = this

      let keys = Object.keys(properties)
      let changedProperties = [] // 提取有变动的属性
      keys.map(key => {
        // let newValue = property.value
        let newValue = properties[key]
        let oldValue = shape.properties.get(key)
        if (newValue !== oldValue) {
          changedProperties.push({
            key,
            oldValue,
            newValue
          })
        }
      })

      if (changedProperties.length > 0) {
        this.editorManager.assignCommand('setProperties', changedProperties, shape, _this.editorManager.getEditor())
        this.editorManager.handleEvents({
          type: 'propertyWindow.propertyChanged',
          elements: [shape],
          key: keys
        })

        // Switch the property back to read mode, now the update is done
        this.currentShapeMode = 'read'
        const event = {
          type: 'event-type-property-value-changed',
          // property: property,
          // oldValue: oldValue,
          // newValue: newValue,
          properties: changedProperties,
          keys: keys
        }

        this.editorManager.dispatchFlowEvent(event.type, event)
      } else {
        this.currentShapeMode = 'read'
      }
    },
    /**
     * 属性编辑保存并更新节点
     */
    // handlebubbleEvents(type, params) {
    handlebubbleEvents() {
      this.updatePropertyInModel({
        properties: this.nodeObjProperties
      })
      this.writeDialog.visible = false
    },
    /**
     * 双击触发
     */
    doubleClick() {},
    /**
     * 双击改变节点后返回值
     */
    doubleClickToChangeVal() {
      // console.log('双击改变节点后返回值', params)
    },
    /**
     * 阶段策略
     */
    stageStrategyFun(obj) {
      this.$emit('stageStrategy', obj)
    },
    /**
     * 流转策略
     */
    sequenseflowStrategyFun(obj) {
      this.$emit('sequenseflowStrategy', obj)
    }
  }
}
</script>
<style lang="scss" scoped>
.flow-content {
  width: 100%;
  height: 100%;
}
::v-deep .flow-content-box {
  height: calc(100% - 47px);
  .stencils .stencil-group {
    margin: 0;
  }
}
.group-name ul li {
  display: block !important;
}
.stencils {
  border-right: 0;
}
::v-deep .ui-draggable {
  display: flex;
  img {
    display: block;
    margin-top: 1px;
  }
  span {
    display: block;
    margin-left: 4px;
  }
}
.edit-dialog ::v-deep .el-dialog {
  width: 720px !important;
}
.save-dialog ::v-deep .el-dialog {
  width: 580px !important;
}
// ::v-deep .editor-toolbar,
// ::v-deep .paletteHelpWrapper {
//   display: none;
// }
::v-deep .stencils .group-name + ul li {
  display: block;
}
::v-deep .paletteHelpWrapper {
  width: 120px !important;
}
::v-deep .editor-toolbar {
  min-height: 40px;
  background-color: #f5f7fa;
  border-bottom: 1px solid #dfe4ed;
  .btn.btn-inverse {
    background-color: #3464cf !important;
    padding: 3px 5px 0px 5px !important;
    height: 34px !important;
    min-width: 34px !important;
  }
  .btn-group {
    margin: 6px 15px 6px 0px;
  }
}

::v-deep .editor-main-wrapper {
  height: 100% !important;
}
::v-deep .canvas_resize_indicator {
  display: none !important;
}
::v-deep .ORYX_Editor svg {
  background-image: none !important;
}
.el-select {
  width: 100%;
}
</style>
